﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NaiveBayesClassifier;

namespace Classifier
{
    public partial class frmMain : Form
    {
        CTrainingSet trainingSet;

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnLoadFromFile_Click(object sender, EventArgs e)
        {
            DialogResult add = MessageBox.Show("Bạn có muốn học lại từ đầu không?", "Hỏi", MessageBoxButtons.YesNo);

            if (add == System.Windows.Forms.DialogResult.Yes)
            {
                LearnFromScratch();
            }
            else
            {

            }

            trainingGV.Tag = "1";
        }

        private void LearnFromScratch()
        {
            string fileName = CUtils.GetOpenFileName();
            if (fileName.Length == 0)
            {
                MessageBox.Show("Chưa chọn file");
                return;
            }

            string[][] data;
            try
            {
                data = CUtils.ReadFileToArray(fileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi: " + ex.Message);
                return;
            }

            if (data.Length <= 1)
            {
                MessageBox.Show("File " + fileName + " bị sai định dạng hoặc không có dữ liệu!");
                return;
            }

            trainingGV.Rows.Clear();

            int numberOfAttributes = data[0].Length;
            trainingGV.ColumnCount = numberOfAttributes;
            for (int i = 0; i < numberOfAttributes; ++i)
                trainingGV.Columns[i].HeaderText = data[0][i];

            for (int i = 1; i < data.Length; ++i)
                trainingGV.Rows.Add(data[i]);
        }

        private void btnLearnFromTable_Click(object sender, EventArgs e)
        {
            if (trainingGV.Tag.ToString().Equals("0"))
            {
                MessageBox.Show("Dữ liệu trong bảng chưa thay đổi!");
                return;
            }

            int n = trainingGV.Columns.Count;
            string[] attributeNames = new string[n - 1];
            for (int i = 0; i < n - 1; ++i)
                attributeNames[i] = trainingGV.Columns[i].HeaderText;

            int m = trainingGV.Rows.Count - 1;
            string[][] data = new string[m][];
            for (int i = 0; i < m; ++i)
            {
                data[i] = new string[n];
                for (int j = 0; j < n; ++j)
                    data[i][j] = trainingGV.Rows[i].Cells[j].Value.ToString();
            }

            trainingSet = new CTrainingSet(attributeNames, data);

            trainingGV.Tag = "0";
        }

        private void btnLoadTestFromFile_Click(object sender, EventArgs e)
        {
            string fileName = CUtils.GetOpenFileName();
            if (fileName.Length == 0)
            {
                MessageBox.Show("Chưa chọn file");
                return;
            }

            string[][] data;
            try
            {
                data = CUtils.ReadFileToArray(fileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi: " + ex.Message);
                return;
            }

            if (data.Length <= 1)
            {
                MessageBox.Show("File " + fileName + " bị sai định dạng hoặc không có dữ liệu!");
                return;
            }

            testGV.Rows.Clear();

            int numberOfAttributes = data[0].Length;
            testGV.ColumnCount = numberOfAttributes;
            for (int i = 0; i < testGV.ColumnCount; ++i)
                testGV.Columns[i].ReadOnly = true;

            for (int i = 0; i < numberOfAttributes; ++i)
                testGV.Columns[i].HeaderText = data[0][i];

            for (int i = 1; i < data.Length; ++i)
                testGV.Rows.Add(data[i]);

            testGV.Tag = "1";
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (testGV.RowCount == 0)
            {
                MessageBox.Show("Chưa có dữ liệu trong bảng!");
                return;
            }

            if (testGV.Tag.ToString().Equals("0"))
            {
                MessageBox.Show("Dữ liệu đã phân loại!");
                return;
            }

            if (trainingSet == null)
            {
                MessageBox.Show("Chưa học tập huấn luyện!");
                return;
            }

            CNaiveBayes naiveBayes = new CNaiveBayes("Naive Bayes", trainingSet);

            int n = testGV.ColumnCount;
            string[] attributeNames = new string[n];
            for (int i = 0; i < n; ++i)
            {
                attributeNames[i] = testGV.Columns[i].HeaderText;
                naiveBayes.TrainOnAttribute(attributeNames[i]);
            }
            naiveBayes.Train();

            int m = testGV.RowCount - 1;
            string[] concept = new string[m];
            for (int i = 0; i < m; ++i)
            {
                string[] attributeValues = new string[n];
                for (int j = 0; j < n; ++j)
                    attributeValues[j] = testGV.Rows[i].Cells[j].Value.ToString();
                IInstance instance = CBaseInstance.CreateInstance("", attributeNames, attributeValues);
                concept[i] = naiveBayes.Classify(instance).GetName();
            }

            testGV.ColumnCount = n + 1;
            testGV.Columns[n].HeaderText = "Class";
            for (int i = 0; i < m; ++i)
                testGV.Rows[i].Cells[n].Value = concept[i];

            testGV.Tag = "0";
        }
    }
}
